package com.cmy.dbTransfer.impl;

import com.cmy.bean.DdlRecord;
import com.cmy.dbTransfer.DBHandler;
import com.cmy.enums.DataBaseEnums;
import com.cmy.factory.DataBaseTransferFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author : Cmy
 * @date : 2024-08-27 11:44
 */
public class MysqlDBTransferImpl extends DBHandler {

    @Override
    public String createDataBaseSql(String name) {
        return "CREATE DATABASE IF NOT EXISTS `" + name + "` DEFAULT CHARACTER SET = `utf8mb4` COLLATE `utf8mb4_general_ci`;";
    }

    @Override
    public String initTableDdlHistory() {
        return "CREATE TABLE IF NOT EXISTS `ddl_history` (\n" +
                "  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,\n" +
                "  `version` varchar(255) NOT NULL,\n" +
                "  `description` varchar(1000) NOT NULL,\n" +
                "  `script` varchar(1000) DEFAULT NULL,\n" +
                "  `checksum` bigint(20) DEFAULT NULL,\n" +
                "  `installed_by` varchar(255) NOT NULL,\n" +
                "  `installed_on` datetime NOT NULL,\n" +
                "  `execution_time` bigint(20) NOT NULL,\n" +
                "  `success` tinyint(1) NOT NULL,\n" +
                "  PRIMARY KEY (`id`)\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
    }

    @Override
    public String generateTableTruncateTable(String tableName) {
        return "TRUNCATE TABLE `" + tableName + "`;\n\n";
    }

    @Override
    public void batchInsert(DdlRecord ddlRecord, JdbcTemplate jdbcTemplate) {
        // 参数校验
        if (ddlRecord == null) {
            throw new IllegalArgumentException("DdlRecord cannot be null");
        }
        if (jdbcTemplate == null) {
            throw new IllegalArgumentException("JdbcTemplate cannot be null");
        }

        List<String> fieldNames = ddlRecord.getFiledNames();
        List<Map<String, Object>> recordList = ddlRecord.getRecordList();

        if (fieldNames == null || fieldNames.isEmpty()) {
            throw new IllegalArgumentException("Field names cannot be empty");
        }
        if (recordList == null || recordList.isEmpty()) {
            throw new IllegalArgumentException("Record list cannot be empty");
        }

        // 构建SQL模板
        String sql = String.format("INSERT INTO %s (%s) VALUES (%s)",
                ddlRecord.getTableName(),
                String.join(", ", fieldNames),
                String.join(", ", Collections.nCopies(fieldNames.size(), "?"))
        );

        // 执行批处理操作
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int rowIndex) throws SQLException {
                Map<String, Object> record = recordList.get(rowIndex);

                // 按字段顺序设置参数
                for (int i = 0; i < fieldNames.size(); i++) {
                    String fieldName = fieldNames.get(i);
                    Object value = record.get(fieldName);

                    // 处理空值 和 空字符串
                    if (value == null || (value instanceof String && StringUtils.isBlank((String) value))) {
                        ps.setNull(i + 1, Types.NULL);
                        continue;
                    }

                    ps.setObject(i + 1, value);

                }
            }

            @Override
            public int getBatchSize() {
                return recordList.size();
            }
        });
    }


    @Override
    public String createTableSql() {
        return "";
    }

    @Override
    public String alterTableColumnsSql() {
        return "";
    }

    @Override
    public String addTableColumnsSql() {
        return "";
    }

    @Override
    public String addTableRecordsSql() {
        return "";
    }

    @Override
    public String removeTableRecordsSql() {
        return "";
    }

    @Override
    public String updateTableRecordsSql() {
        return "";
    }

    private static String escapeSql(String str) {
        return str.replace("'", "''");
    }
}

    